package main

import (
	"bytes"
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"github.com/gogf/gf/encoding/gurl"
	"github.com/gogf/gf/util/gconv"
	"io/ioutil"
	"log"
	"net/http"
	"strings"
	"time"
)

const (
	DingDingUrl = "https://oapi.dingtalk.com/robot/send?access_token=56afcf0da4735e3be0e94a37c81b5f766843eabb57d0742c25d5a85df7fa9502"
	SECRET      = "SECeea5b13f3ea4fa076039e97d9f591ff0a6403ee85a791d8dd52e96bbb129e6bb"
)

type Text struct {
	Content string `json:"content"`
}

type Msg struct {
	MsgType string `json:"msgtype"`
	Text    Text   `json:"text"`
}

type Alert struct {
	Status      string            `json:"status"`
	Labels      map[string]string `json:"labels"`
	Annotations map[string]string `json:"annotations"`
	StartsAt    time.Time         `json:"startsAt"`
	EndsAt      time.Time         `json:"endsAt"`
}

type Notification struct {
	Version           string            `json:"version"`
	GroupKey          string            `json:"groupKey"`
	Status            string            `json:"status"`
	Receiver          string            `json:"receiver"`
	GroupLabels       map[string]string `json:"groupLabels"`
	CommonLabels      map[string]string `json:"commonLabels"`
	CommonAnnotations map[string]string `json:"commonAnnotations"`
	ExternalURL       string            `json:"externalURL"`
	Alerts            []Alert           `json:"alerts"`
}

func main() {
	ts, sign := GenSign()
	fmt.Println(ts, sign)

	http.HandleFunc("/send", Dingtalk)
	http.ListenAndServe(":8090", nil)
}

func Dingtalk(w http.ResponseWriter, r *http.Request) {
	b, _ := ioutil.ReadAll(r.Body)
	defer r.Body.Close()

	var notification Notification
	log.Println(string(b))
	json.Unmarshal(b, &notification)
	log.Println(notification)

	contents := []string{}
	headers := fmt.Sprintf("group: %s  status:%s", notification.CommonLabels["group"], notification.Status)
	log.Println(headers)
	contents = append(contents, headers)

	for _, each := range notification.Alerts {
		body := fmt.Sprintf("status:%s %s", each.Status, each.Annotations["summary"])
		contents = append(contents, body)
	}
	strings.Join(contents, "\n")
	msg := Msg{
		MsgType: "text",
		Text: Text{
			Content: strings.Join(contents, "\n"),
		},
	}

	ts, sign := GenSign()
	url := DingDingUrl + "&timestamp=" + ts + "&sign=" + sign
	msgJson, _ := json.Marshal(msg)
	fmt.Println("send data:", string(msgJson))
	req, _ := http.NewRequest("POST", url, bytes.NewBuffer(msgJson))
	req.Header.Add("Content-Type", "application/json")
	client := http.Client{}
	res, _ := client.Do(req)
	defer res.Body.Close()

	body, _ := ioutil.ReadAll(res.Body)
	log.Printf("%s\n", body)
	fmt.Fprint(w, "hello world\n")
}

func GenSign() (string, string) {
	ts := gconv.String(time.Now().Unix() * 1000)
	signStr := ts + "\n" + SECRET

	hash := ComputeHmacSha256(signStr, SECRET)

	cliSign := gurl.Encode(hash)

	return ts, cliSign
}

func ComputeHmacSha256(message string, secret string) string {
	key := []byte(secret)
	h := hmac.New(sha256.New, key)
	h.Write([]byte(message))
	//	fmt.Println(h.Sum(nil))
	sha := hex.EncodeToString(h.Sum(nil))
	//	fmt.Println(sha)

	//	hex.EncodeToString(h.Sum(nil))
	return base64.StdEncoding.EncodeToString([]byte(sha))
}
